package mmc.cell3;

import java.util.LinkedList;
import java.util.List;

import mmc.Constants;
import mmc.cell.CellPosition;
import mmc.server.Player;
import mmc.server.Server;

public class RangeSweeper implements Runnable{
	
	ServerCellManagerImpl cm;
	//long lastSweep = System.nanoTime();
	private List<CellPosition> toLoad = java.util.Collections.synchronizedList(new LinkedList<CellPosition>());
	private volatile boolean quit = false;
	
	public static long SWEEP_INTERVAL=(long) 1e9;
	
	public RangeSweeper(ServerCellManagerImpl man){
		this.cm=man;
		
		new Thread(this).start();
	}
	
	public void sweep(){
		/*
		if(!toLoad.isEmpty()||lastSweep + SWEEP_INTERVAL > System.nanoTime())
			return;
			*/
		
		//lastSweep = System.nanoTime();
		
		if(Server.instance.getScene()!=null && Server.instance.getScene().getPlayers()!=null)
			for(Player p : Server.instance.getScene().getPlayers()){
				CellPosition p_chunk = new CellPosition(p,Constants.CHUNK_MASK);
				int playerView_Chunks = (int) Math.max((p.viewDistance+1.5f*Constants.CHUNK_BLOCKS)/Constants.CHUNK_BLOCKS,2);
				
				CellPosition cp = new CellPosition(0,0,0);
				
				for(int i=-playerView_Chunks;i<playerView_Chunks;i++){
					cp.x = p_chunk.x + i*Constants.CHUNK_BLOCKS;
					for(int j=-playerView_Chunks;j<playerView_Chunks;j++){
						cp.y = p_chunk.y + j*Constants.CHUNK_BLOCKS;
						for(int k=-playerView_Chunks;k<playerView_Chunks;k++){
							cp.z = p_chunk.z + k*Constants.CHUNK_BLOCKS;
							
							if(!cm.isChunkLoaded(cp))
								toLoad.add(new CellPosition(cp.x,cp.y,cp.z));
						}
					}
				}
			}
	}

	void quit(){
		System.out.println("Shutting down Generator ...");
		quit=true;
		synchronized (this) {
			this.notify();
		}
	}
	
	@Override
	public void run() {
		try{
			while(!quit){
				
				if(toLoad.isEmpty())
					sweep();
				
				if(toLoad.isEmpty()){
					cm.getChunkGenerator().clearCache();
					
					synchronized (this) {
						try {
							this.wait(SWEEP_INTERVAL/(long)1e6);
						} catch (InterruptedException e) {}
					}
				}else{
					if(!toLoad.isEmpty()){
						cm.assertChunkLoaded(toLoad.remove(toLoad.size()-1));
					}
				}
			}
		}finally{
			System.out.println("ChunkGenerator: "+getClass().getName()+" thread died");
		}
	}
}
